/*
  S.M.A.C.K - An operating system kernel
  Copyright (C) 2010,2011 Mattias Holm and Kristian Rietveld
  For licensing and a full list of authors of the kernel, see the files
  COPYING and AUTHORS.
*/

#ifndef KERNEL_VFS_FAT16_H__
#define KERNEL_VFS_FAT16_H__

#include <stdint.h>

/* References:
 * http://home.teleport.com/~brainy/fat16.htm
 * http://en.wikipedia.org/wiki/File_Allocation_Table
 */

typedef struct
{
  uint8_t active;
  uint8_t begin_head;
  uint16_t begin_cs;
  uint8_t type;
  uint8_t end_head;
  uint16_t end_cs;
  uint32_t lba_begin;
  uint32_t num_sectors;
} __attribute__((__packed__)) mbr_partition_entry_t;

typedef struct
{
  uint8_t boot_code[446];
  mbr_partition_entry_t partitions[4];
  uint16_t exec_marker;
} __attribute__((__packed__)) mbr_t;

typedef struct
{
  uint8_t jump_code[3];
  char oem[8];
  uint16_t bytes_per_sector;
  uint8_t sectors_per_cluster;
  uint16_t reserved_sectors;
  uint8_t num_fat_copies;
  uint16_t max_root_entries;
  uint16_t num_sectors_below_32mb;
  uint8_t media_descriptor;
  uint16_t sectors_per_fat;
  uint16_t sectors_per_track;
  uint16_t num_heads;
  uint32_t num_hidden_sectors;
  uint32_t num_sectors;
  uint16_t drive_number;
  uint8_t ext_signature;
  uint32_t serial_no;
  char vol_name[11];
  char fat_name[8];
  uint8_t exec_code[448];
  uint16_t exec_marker;
} __attribute__((__packed__)) fat16_super_t;

#define FAT16_ENTRY_FREE 0x0000
#define FAT16_ENTRY_RESERVED 0x0001
#define FAT16_USED_LO 0x0002
#define FAT16_USED_HI 0xffef
#define FAT16_BAD_SECTOR 0xfff7
#define FAT16_EOC_LO 0xfff8
#define FAT16_EOC_HI 0xffff

#define FAT16_ENTRY_AVAILABLE_LAST 0x0
#define FAT16_INITIAL_IS_E5 0x05
#define FAT16_DOT_ENTRY 0x2e
#define FAT16_AVAILABLE_ERASED 0xe5

#define FAT16_READONLY  0x1
#define FAT16_HIDDEN    0x2
#define FAT16_SYSTEM    0x4
#define FAT16_VOLUME    0x8
#define FAT16_LFN       0xf
#define FAT16_DIRECTORY 0x10
#define FAT16_ARCHIVE   0x20

typedef struct
{
  char name[8];
  char extension[3];
  uint8_t attribute;
  uint8_t reserved_nt;
  uint8_t create_time_10ms;
  uint16_t create_time_hm;
  uint16_t create_date;
  uint16_t last_access_date;
  uint16_t extended_attribute;
  uint16_t mtime;
  uint16_t mdate;
  uint16_t start_of_file;
  uint32_t file_size;
} __attribute__((__packed__)) fat16_dirent_t;


void fat16_init(void);

#endif /* ! KERNEL_VFS_FAT16_H */
